#include <math.h>

///////////////////////////////////////////////
// Camera by Slawomir Marcjanski
// Part of ClearLightEngine

////////////////////////

enCamera::enCamera()
{

View.pX = -7.31 ;
View.pY = -94.0f ;
View.pZ = -18.0f ;
View.rX = -7.5 ;
View.rY = -94 ;
View.rZ = -21.5 ;
Color.elements[0] = 1;
Color.elements[1] = 1;
Color.elements[2] = 1;
visible = true;
}


void enCamera::Deploy()
{
// Update Light Position
GLfloat LightPosition[]=	{ View.rX , View.rY, View.rZ, 1.0f }; 
glLightfv(ln, GL_POSITION, LightPosition);
//////////////////////////

gluLookAt(View.pX, View.pY, View.pZ, View.rX, View.rY, View.rZ, 0, 1, 0);

}

void enCamera::LookRight()
{

float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));

float y = -0.03f;
float x = 0;
float z = 0;

if(x) 
	{
		View.rZ = (float)(View.pZ + sin(x)*ty + cos(x)*tz);
		View.rY = (float)(View.pY + cos(x)*ty - sin(x)*tz);
	}
	if(y) 
	{
		View.rZ = (float)(View.pZ + sin(y)*tx + cos(y)*tz);
		View.rX = (float)(View.pX + cos(y)*tx - sin(y)*tz);
	}
	if(z) 
	{
		View.rX = (float)(View.pX + sin(z)*ty + cos(z)*tx);		
		View.rY = (float)(View.pY + cos(z)*ty - sin(z)*tx);
	}


}



void enCamera::LookLeft()
{

float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));

float y = 0.03f;
float x = 0;
float z = 0;

if(x) 
	{
		View.rZ = (float)(View.pZ + sin(x)*ty + cos(x)*tz);
		View.rY = (float)(View.pY + cos(x)*ty - sin(x)*tz);
	}
	if(y) 
	{
		View.rZ = (float)(View.pZ + sin(y)*tx + cos(y)*tz);
		View.rX = (float)(View.pX + cos(y)*tx - sin(y)*tz);
	}
	if(z) 
	{
		View.rX = (float)(View.pX + sin(z)*ty + cos(z)*tx);		
		View.rY = (float)(View.pY + cos(z)*ty - sin(z)*tx);
	}


}


void enCamera::Up()
{

float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));

View.pY += 0.6 ;
View.rY += 0.6 ;


}

void enCamera::Down()
{

float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));

View.pY -= 0.6 ;
View.rY -= 0.6 ;
}


void enCamera::Forvard()
{
float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));


View.pX += tx;
View.pZ += tz ;
View.pY += ty ;

View.rX += tx ;
View.rZ += tz;
View.rY += ty ;

}

void enCamera::Back()
{
float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));

View.pX -= tx;
View.pZ -= tz;
View.pY -= ty;

View.rX -= tx ;
View.rZ -= tz;
View.rY -= ty ;

}
///////////////////////////////////////////////////////////////////
// Color
void enCamera::SetColor(float r, float g, float b)
{
Color.elements[0] = r;
Color.elements[1] = g;
Color.elements[2] = b;
}
    void enCamera::MoreGreen()
    {
    if( Color.elements[1] < 1) Color.elements[1]  += 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }

    void enCamera::MoreRed()
    {
    if( Color.elements[0] < 1)    Color.elements[0]  += 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }

    void enCamera::MoreBlue()
    {
    if( Color.elements[2] < 1)    Color.elements[2]  += 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }
    ////////////////////////////////////////////////
    void enCamera::LessGreen()
    {
       if( Color.elements[1] > 0)    Color.elements[1] -= 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }

    void enCamera::LessRed()
    {
    if( Color.elements[0] > 0)     Color.elements[0] -= 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }

    void enCamera::LessBlue()
    {
    if( Color.elements[2] > 0)     Color.elements[2]  -= 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }
    ////////////////////////////////////////////
    void enCamera::MoreLight()
    {
        if( Color.elements[0] < 1)   Color.elements[0]  += 0.05;
        if( Color.elements[1] < 1)     Color.elements[1]  += 0.05;
        if( Color.elements[2] < 1)     Color.elements[2] += 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }
    
    void enCamera::LessLight()
    {
     if( Color.elements[0] > 0)     Color.elements[0] -= 0.05;
     if( Color.elements[1] > 0)     Color.elements[1]  -= 0.05;
     if( Color.elements[2] > 0)     Color.elements[2]  -= 0.05;
    GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
    	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
    }

////////////////////////////////////////////////////////////


void enCamera::EnableLight()
{
GLfloat LightAmbient[]=		{ 0.1f, 0.1f, 0.1f, 1.0f };
GLfloat LightDiffuse[]=		{ Color.elements[0], Color.elements[1], Color.elements[2], 1.0f };
GLfloat LightPosition[]=	{ View.pX , View.pY, View.pZ, 1.0f };   
    
    glLightfv(ln, GL_AMBIENT, LightAmbient);	
	glLightfv(ln, GL_DIFFUSE, LightDiffuse);	
	glLightfv(ln, GL_POSITION,LightPosition);	
glEnable(ln);
}

void enCamera::DisableLight()
{
glDisable(ln);
}

///////////////////////////////////////////////////


void enCamera::DrawCamera()
{
if(visible)
{
        glBegin(GL_POINTS);
        glVertex3f(Color.elements[0], Color.elements[0], Color.elements[0]);        
        glEnd();
}

}

void enCamera::StepLeft()
{
float xDir, yDir, zDir = 0;
float xCross, yCross, zCross = 0;
float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));

xCross = (ty * 0) - (tz * 1);
yCross = (tz * 0) - (tx * 0);
zCross = (tx * 1) - (ty * 0);

View.pX -= xCross;
View.pZ -= zCross ;
View.pY -= yCross ;

View.rX -= xCross ;
View.rZ -= zCross;
View.rY -= yCross ;

}

void enCamera::StepRight()
{
float xDir, yDir, zDir = 0;
float xCross, yCross, zCross = 0;
float tx = ((View.rX - View.pX));
float tz = ((View.rZ - View.pZ));
float ty = ((View.rY - View.pY));

xCross = (ty * 0) - (tz * 1);
yCross = (tz * 0) - (tx * 0);
zCross = (tx * 1) - (ty * 0);

View.pX += xCross;
View.pZ += zCross ;
View.pY += yCross ;

View.rX += xCross ;
View.rZ += zCross;
View.rY += yCross ;

}


enCameraListAdmin::enCameraListAdmin()
{
first = NULL;
last = NULL;
act = NULL;
cameras = 0;
selected = 0;
}

void enCameraListAdmin::Add()
{
    if(!first)
    {
    first = new enCameraListElement;
    first->Data = new enCamera;
    first->Next = NULL;
    first->Data->ln = GL_LIGHT0;
    act = first;
    last = first;     
    cameras++;
    selected = cameras;    
   
    }
    else
    {
    GLuint ln = last->Data->ln;
    last->Next = new enCameraListElement;
    last = last->Next;
    last->Data = new enCamera;
    last->Next = NULL;
    last->Data->ln = ln+1;    
    act = last;
    cameras ++;
    selected = cameras;
    }


}

void enCameraListAdmin::Deploy()
{
PointerSet();    
act->Data->Deploy();
}

void enCameraListAdmin::SelNext()
{
if(selected < cameras) selected++;
printf("Kamera %d\n", selected);
}

void enCameraListAdmin::SelPrev()
{
if(selected > 0) selected--;
printf("Kamera %d\n", selected);
}

void enCameraListAdmin::PointerSet()
{
act = first;
int i = 1;
if(!act) return;
    while(i < selected)
    {
    act->Data->DrawCamera();
    if(act->Next == NULL) break;
    act = act->Next;
    i++;
    }
}

    void enCameraListAdmin::StepLeft()  {PointerSet(); act->Data->StepLeft(); }
    void enCameraListAdmin::StepRight() {PointerSet(); act->Data->StepRight(); }
    void enCameraListAdmin::Forvard() {PointerSet(); act->Data->Forvard(); }
    void enCameraListAdmin::Back() {PointerSet(); act->Data->Back(); }
    void enCameraListAdmin::Up() {PointerSet(); act->Data->Up(); }
    void enCameraListAdmin::Down() {PointerSet(); act->Data->Down(); }
    void enCameraListAdmin::LookLeft() {PointerSet(); act->Data->LookLeft(); }
    void enCameraListAdmin::LookRight() { PointerSet(); act->Data->LookRight(); }
    void enCameraListAdmin::DeployAct() { PointerSet(); act->Data->Deploy(); }
    void enCameraListAdmin::DrawCamera() {PointerSet(); act->Data->DrawCamera(); }
    void enCameraListAdmin::SetColor(float r, float g, float b) {PointerSet(); act->Data->SetColor(r, g, b); }
            void enCameraListAdmin::MoreLight() {PointerSet(); act->Data->MoreLight(); }
            void enCameraListAdmin::LessLight() {PointerSet(); act->Data->LessLight(); }
            void enCameraListAdmin::LessRed() {PointerSet(); act->Data->LessRed(); }
            void enCameraListAdmin::MoreRed() { PointerSet(); act->Data->MoreRed(); }
            void enCameraListAdmin::LessGreen() {PointerSet(); act->Data->LessGreen(); }
            void enCameraListAdmin::MoreGreen() {PointerSet(); act->Data->MoreGreen(); }
            void enCameraListAdmin::LessBlue() {PointerSet(); act->Data->LessBlue(); }
            void enCameraListAdmin::MoreBlue() {PointerSet(); act->Data->MoreBlue(); }
            void enCameraListAdmin::EnableLight() {PointerSet(); act->Data->EnableLight(); }
            void enCameraListAdmin::DisableLight() {PointerSet(); act->Data->DisableLight(); }
